package com.wno704.intf.service.impl;

import com.wno704.intf.config.WnoConfig;
import com.wno704.intf.entity.IntfScript;
import com.wno704.intf.service.IntfScriptService;
import com.wno704.system.util.CacheUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @ClassName IntfServiceImpl
 * @Description TODO
 * @Author wno704
 * @Date 2023/4/13 16:56
 * @Version 1.0
 */
@Service("IntfService")
@RequiredArgsConstructor
public class IntfScriptServiceImpl implements IntfScriptService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    WnoConfig wnoConfig;
    
    @Override
    public int init() {
        String sql = "SELECT INTF_ID,METHOD,URL,SCRIPT,STATUS,IS_LOG,REMARK,CREATE_TIME FROM " + wnoConfig.getTablePrefix() + "SCRIPT WHERE  STATUS = '0' ";
        List<IntfScript> intfList = this.jdbcTemplate.query(sql, new BeanPropertyRowMapper<IntfScript>(IntfScript.class));
        intfList.forEach(intf -> {
            readIntf(intf);
        });
        return intfList.size();
    }

    private void readIntf(IntfScript intf) {
        String upSql = "";
        if ("MySQL".equals(wnoConfig.getIntfDB()) || "PostgreSQL".equals(wnoConfig.getIntfDB())) {
            upSql = "UPDATE " + wnoConfig.getTablePrefix() + "SCRIPT  SET READ_TIME = now() WHERE INTF_ID = ? ";
        }
        if ("Oracle".equals(wnoConfig.getIntfDB())) {
            upSql = "UPDATE " + wnoConfig.getTablePrefix() + "SCRIPT  SET READ_TIME = sysdate WHERE INTF_ID = ? ";
        }
        this.jdbcTemplate.update(upSql, new Object[]{intf.getIntfId()});

        String key = "intf-" + intf.getMethod() + "-" + intf.getUrl();
        CacheUtil.remove(key);
        if (IntfScript.runStatus.NORMAL.getValue().equals(intf.getStatus())) {
            CacheUtil.put(key, intf);
        }
    }

    @Override
    public int load() {
        String sql = "";
        if ("MySQL".equals(wnoConfig.getIntfDB())) {
            sql = "SELECT INTF_ID,METHOD,URL,SCRIPT,STATUS,IS_LOG,REMARK,CREATE_TIME FROM " + wnoConfig.getTablePrefix() + "SCRIPT WHERE CREATE_TIME >=  ADDDATE(NOW(), INTERVAL -30 SECOND) ";
        }
        if ("PostgreSQL".equals(wnoConfig.getIntfDB())) {
            sql = "SELECT INTF_ID,METHOD,URL,SCRIPT,STATUS,IS_LOG,REMARK,CREATE_TIME FROM " + wnoConfig.getTablePrefix() + "SCRIPT WHERE  CREATE_TIME >=  NOW()-interval '30 SECOND' ";
        }
        if ("Oracle".equals(wnoConfig.getIntfDB())) {
            sql = "SELECT INTF_ID,METHOD,URL,SCRIPT,STATUS,IS_LOG,REMARK,CREATE_TIME FROM " + wnoConfig.getTablePrefix() + "SCRIPT WHERE  CREATE_TIME >=  SYSDATE - 30/(24*60*60) ";
        }
        List<IntfScript> intfList = this.jdbcTemplate.query(sql, new BeanPropertyRowMapper<IntfScript>(IntfScript.class));
        intfList.forEach(intf -> {
            readIntf(intf);
        });
        return intfList.size();
    }

    @Override
    public IntfScript getScript(String method, String url) {
        String key = "intf-" + method + "-" + url;
        IntfScript intf = CacheUtil.get(key);
        if (ObjectUtils.isEmpty(intf)) {
            String sql = "SELECT INTF_ID,METHOD,URL,SCRIPT,STATUS,IS_LOG,REMARK,CREATE_TIME FROM " + wnoConfig.getTablePrefix() + "SCRIPT WHERE  STATUS = '0' AND METHOD = ? AND ? like URL ";
            List<IntfScript> intfList = this.jdbcTemplate.query(sql, new BeanPropertyRowMapper<IntfScript>(IntfScript.class), new Object[]{method, url});
            intf = intfList.size() > 0 ? intfList.get(0) : null;
        }
        return intf;
    }
}
